#ifndef __DB_UTIL_H__
#define __DB_UTIL_H__
//#define __DB_DEBUG
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <glob.h>
#include <stdbool.h>
#include <pthread.h>
#include <stdarg.h>
#include <sys/time.h>
#pragma pack(1)
#define DEF_STR_SIZ 128
#define DEF_LIST_NUM 16
#define DEF_FILE_MODE 0644
#define DEF_PAIR_NUM 16
#define MAX_PATH 128
#define BLOCKSIZ 512
typedef unsigned int uint32;
typedef int int32;
typedef unsigned char uchar;
typedef long long int64;
typedef unsigned long long uint64;
typedef unsigned short uint16;
typedef short int16;
#ifndef INT16_MAX
#define INT16_MAX 0x7fff
#endif
struct bstring{
    int max;
	int siz;
	char *array;
};
struct freepage{
    char magic[4];
	uint64 nextpg;
};
struct strlist{
    struct bstring **str_array;
	int siz;
	int max;
};
struct item{
    struct bstring *key;
	//struct bstring *val;
	//void *key;
	void *val;
	uint16 hash;
	struct item *left;
	struct item *right;
	struct item *next;
	struct item *pre;
};
struct harray{
    struct item **buckets;
	struct item *last;
	struct item *first;
	int nbucket;
	int nrec;
	struct item *iter;
};
struct sortitem{
    struct bstring *key;
	void *data;
};
/*
struct bnode{
    char *key;
	int ksiz;
	void *value;
	struct bnode *left;
	struct bnode *right;
};
struct twoidxtree{
    struct twoindex *root;
	int (cmp1*)(char *k1,int s1,char *k2,int s2);
	int (cmp2*)(char *k1,int s1,char *k2,int s2);
}
struct twoindex{
    char *key1;
	int ksiz1;
	char *key2;
	int ksiz2;
	struct twoindex *left;
	struct twoindex *right;
};*/
struct stack{
   void *buf;
   int top;
   int siz;
};
#define DEF_STACK_BUF 8
#define STACK_NEW(s,type)\
   do{\
       (s)=malloc(sizeof(struct stack));\
	   (s)->buf=malloc(DEF_STACK_BUF*sizeof(type));\
	   (s)->top=0;\
	   (s)->siz=DEF_STACK_BUF;\
   }while(0)
#define STACK_DEL(s)\
   do{\
        if((s)->buf!=NULL) free((s)->buf);\
		free(s);\
   }while(0)
#define STACK_PUSH(s,type,val)\
   do{\
        if((s)->top>=(s)->siz){\
		    (s)->siz<<=1;\
		    (s)->buf=realloc((s)->buf,(s)->siz);\
		}\
		*((type*)(s)->buf+s->top)=(val);\
		(s)->top++;\
   }while(0)
#define STACK_POP(s,type,val)\
   do{\
        if((s)->top>0)\
		    val=*((type*)(s)->buf+(--(s)->top));\
		else val=(type)0;\
   }while(0)
#define STACK_CLEAR(s) (s)->top=0
struct hashcache{
    struct item **buckets;
	struct item *last;
	struct item *first;
	int nbucket;
	int nrec;
	int maxbytes;
	int curbytes;
	double incratio;
	int initsiz;
	struct item *iter;
	struct item *ffirst;
	struct item *flast;
};
#define FREEPAGEMAGIC "free"
#define FREEHEAD (sizeof(char)*4+sizeof(uint64))
int seekwrite(int fd,char *buf,int32 len,uint64 offset);
int seekread(int fd,char *buf,int32 len,uint64 offset);
int lg2(int num);
uint32 prim(int num);
int readn(int fd,char *buf,int len);
int writen(int fd,char *buf,int len);
int endwith(char *str,int ssiz,char *end,int esiz);
int mystrncmp(char *a,char *b,int len);

struct bstring* strnew(int siz);
struct bstring *strcreate(char *str,int len);
int strassign(struct bstring *str,char *cs,int siz);
int stradd(struct bstring *str,char *cs,int siz);
void strdel(struct bstring *str);
int bstrdup(struct bstring *sstr,struct bstring *tstr);
int strcompare(struct bstring *str,char *peer,int siz);
int strcomparestr(struct bstring *str,struct bstring *ref);
#define STRVAL(str) (str)->array
#define STRLEN(str) (str)->siz
void sort64(uint64 a[],int len);

struct strlist* listcreate(int num);
int listadd(struct strlist *list,struct bstring *str);
struct bstring* listget(struct strlist *list,int i);
int listerase(struct strlist *list,int i);
void listdel(struct strlist *list);

struct harray* hashcreate(int nb);
int hashput(struct harray *ha,char *key,int ksiz,void *val);
int hashputrep(struct harray *ha,char *key,int ksiz,void *val);
int hashputkeep(struct harray *ha,struct bstring* key,void *val);
int hashputstr(struct harray *ha,struct bstring *key,struct bstring *val);
struct bstring* hashgetstr(struct harray *ha,struct bstring *key);
void* hashget(struct harray *ha,char *key,int ksiz);
void* hasherase(struct harray *ha,char *key,int ksiz);
int hasherasestr(struct harray *ha,char *key,int ksiz);
void hashdel(struct harray *ha,void(*)(void*));
void hashdelstr(struct harray *ha);
void hashand(struct harray *ha,struct harray *hb);
void hashor(struct harray *ha,struct harray *hb);
struct harray *strtohash(char *str,int siz);
void hashheadout(struct harray *ha,int n,void(*)(void*));
void hashtailout(struct harray *ha,int n,void(*)(void*));
int recput(struct harray *ha,char *key,char *val);
int hashexsit(struct harray *ha,char *key,int ksiz);
void* hashfirst(struct harray *ha,struct bstring **key);
void *hashlast(struct harray *ha,struct bstring **key);
void* hashnext(struct harray *ha,struct bstring **key);
void *hashpre(struct harray *ha,struct bstring **key);
#define HASHNREC(ha) (ha)->nrec
int xatoi(char *key,int len);
int hashtraverse(struct harray* ha);

#ifdef __DB_DEBUG
#define DEBUG(func) func
#else
#define DEBUG(func)
#endif
#endif
